package cn.com.ylpw.web.util;

import java.io.UnsupportedEncodingException;
import java.lang.reflect.Array;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.commons.codec.binary.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Qualifier;

import cn.com.ylpw.web.model.product.TunionBean;
import cn.com.ylpw.web.model.seat.SeatDetails;
import cn.com.ylpw.web.model.seat.SeatResponse;
import cn.com.ylpw.web.model.seat.SeatResult;
import cn.com.ylpw.web.order.controller.OrderController;
import cn.com.ylpw.web.util.Constants.OnlineSeat;


/**
 * @description 
 * 功能描述: 	订单工具类
 * @author 于旺
 * @date   2015年9月23日13:56:31
 * @Copyright ©2003-2015 北京春秋永乐文化传播有限公司. All Rights Reserved.
 * @version 新架构 1.0
 */
public class OrderUtils {
	@Qualifier("configproperties")
	static Properties property;
	public static final Logger log = LoggerFactory.getLogger(OrderUtils.class);
	/**
	 * @description 
	 * 功能描述: 自动校验票价张数
	 * @author 		  作         者: 张嘉杰
	 * @param	             参         数: specialStr 目标字符串 类似[11111,22222,33333,44444^5,3]
	 * @return       返回类型: Map<String,Integer> [{22222=3, 44444=1, 33333=1, 11111=5}]
	 * @createdate   建立日期：Aug 22, 20138:49:34 PM
	 */
	public static Map<String,Integer> SpecialTicketNum(String specialStr){
		Map<String,Integer> map = new HashMap<String, Integer>();
		if(!specialStr.contains("^"))
		{
			return null;
		}
		String[] params = specialStr.split("\\^");
		if(params.length == 1)
		{
			map.put(params[0],StringUtil.parseInt(params[1]));
			return map;
		}
		
		String[] keys	= params[0].split(",");
		String[] values = params[1].split(",");
		
		//值不足自动补齐
		if(values.length < keys.length)
		{
			values = (String[]) expand(values,keys.length);	//动态增加数组
			for (int i = values.length-1; i >= 0; i--) 
			{
				if(values[i]!=null) break;
				values[i] = "1";
			}
		}
		
		//以key的长度遍历
		for (int i = 0; i < keys.length; i++) 
		{
			Integer value = StringUtil.parseInt(values[i]);
			map.put(keys[i],  (map.containsKey(keys[i])) ? StringUtil.parseInt(map.get(keys[i]).toString()) + value : value );
		}
		return map;
		
	}
	/**
	 * @description 
	 * 功能描述: 动态增加数组
	 * @author 		  作         者: 张嘉杰
	 * @param	             参         数: array 目标数组
	 * 						  newSize 新长度
	 * @return       返回类型: 新数组
	 * @createdate   建立日期：Aug 22, 20138:41:17 PM
	 */
	public static Object expand(Object array, int newSize){  
        if  (array == null)
        {  
        	return null;  
        }  
        Class c = array.getClass();
        if  (c.isArray())
        {  
            int len = Array.getLength(array);  
            if(len >= newSize)  
            {  
                return  array;  
            } else {  
                Class cc = c.getComponentType();
                Object newArray = Array.newInstance(cc, newSize);
                System.arraycopy(array, 0, newArray, 0, len);
                return newArray;
            }  
        } else {  
            throw new ClassCastException("必须为数组...");  
        }  
	} 
	/**
	 * 
	 * @description 
	 * 功能描述: 读取cookie *注 都做了url解码
	 * @author 		  作         者: 卢春梦
	 * @param		  参         数: 
	 * @return       返回类型: 
	 * @createdate   建立日期：2013-8-9下午4:35:47
	 */
	public static String getCookie(HttpServletRequest request, String key) throws UnsupportedEncodingException{
		Cookie[] cookies = request.getCookies();
		if(null != cookies){
			for (Cookie cookie : cookies) {
				if (key.equals(cookie.getName())) {
					return URLDecoder.decode(cookie.getValue(), "utf-8");
				}
			}
		}
		return null;
	}
	
	/**
	 * @description 
	 * 功能描述: Base64带key解密
	 * @author 		  作         者: 张嘉杰
	 * @param	             参         数: ESDKEY 密钥
	 * 						  base64Message 需要解密字符串
	 * @return       返回类型: 解密后的字符串
	 * @createdate   建立日期：Aug 1, 201312:08:20 PM
	 */
	public static String decrypt(String base64Message,String... ESDKEY){
		try {
			//解密的Key   
	  	  	String strKey = (ESDKEY.length==0) ? Constants.BASE64_DEFAULT_ESDKEY : ESDKEY[0];
		  	//已加密的Base64字串   
		  	String strEncrypted = base64Message;   
		  	//先將Base64字串转码byte[]   
		  	Base64 objBase64 = new Base64();   
		  	byte[] bysDecoded = objBase64.decode(strEncrypted.getBytes());   
		  	//建立解密所需的Key. 因为加密时的key是用UTF-8转换, 所以用UTF-8转  
		  	DESKeySpec objDesKeySpec = new DESKeySpec(strKey.getBytes("UTF-8"));   
		  	SecretKeyFactory objKeyFactory = SecretKeyFactory.getInstance("DES");   
		  	SecretKey objSecretKey = objKeyFactory.generateSecret(objDesKeySpec);   
		  	//设置DES/ECB/NoPadding的Cipher   
		  	//ECB对应到.Net的CipherMode.ECB   
		  	//NoPadding对应到.Net的PaddingMode.None  ==> DES/ECB/NoPadding
		  	//NoPadding对应到.Net的PaddingMode.PKCS7 ==> DES/ECB/NoPadding
		  	Cipher objCipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
		  	//设定为解密模式, 并设定解密的key   
		  	objCipher.init(Cipher.DECRYPT_MODE, objSecretKey);   
		  	//输出解密后的字串. 因为加密时的key是用UTF-8转换, 所以用UTF-8转回去 
		  	String strDecrypted = new String(objCipher.doFinal(bysDecoded), "utf-8").trim();   
		  	log.info("字符串{},Base64 解密成功:{}",base64Message,strDecrypted);
		  	return strDecrypted;
	  } catch (Exception e) {
		  	log.error("Base64解析失败...",e);
		  	return null;
	  }
		
	}
	/**
	 * @description 
	 * 功能描述: Base64带key加密
	 * @author 		  作         者: 张嘉杰
	 * @param	             参         数: ESDKEY 密钥
	 * 						  message 需要加密字符串
	 * @return       返回类型: 加密后的字符串
	 * @createdate   建立日期：Aug 1, 201312:07:29 PM
	 */
	public static String encrypt(String message,String... ESDKEY){
		try {
			//加密的Key   
	  	  	String strKey = (ESDKEY.length==0) ? Constants.BASE64_DEFAULT_ESDKEY : ESDKEY[0];
	  	  	//字符串  byte[] 数组
	  	  	byte[] strEncrypted = message.getBytes();
	  	  	//建立加密所需的Key. 因为加密时的key是用UTF-8转换, 所以用UTF-8转
		  	DESKeySpec objDesKeySpec = new DESKeySpec(strKey.getBytes("UTF-8"));
		  	SecretKeyFactory objKeyFactory = SecretKeyFactory.getInstance("DES");
		  	SecretKey objSecretKey = objKeyFactory.generateSecret(objDesKeySpec);   
		  	//设置DES/ECB/NoPadding的Cipher
		  	//ECB对应到.Net的CipherMode.ECB
		  	//NoPadding对应到.Net的PaddingMode.None  ==> DES/ECB/NoPadding
		  	//NoPadding对应到.Net的PaddingMode.PKCS7 ==> DES/ECB/NoPadding
		  	Cipher objCipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
		  	//设定为加密模式, 并设定加密的key
		  	objCipher.init(Cipher.ENCRYPT_MODE, objSecretKey);
		  	//输出加密后的字串. 因为加密时的key是用UTF-8转换, 所以用UTF-8转回去
		  	Base64 objBase64 = new Base64();
		  	byte[] bysDecoded = objBase64.encode(objCipher.doFinal(strEncrypted));
		  	String Base64strDecrypted = new String(bysDecoded,"utf-8").trim();
		  	log.info("字符串{},Base64 加密成功:{}",message,Base64strDecrypted);
		  	return Base64strDecrypted;
		} catch (Exception e) {
			log.error("Base64解析失败...",e);
			return null;
		}
	}	
	
	/**
	 * 电子票特殊流程 返回随机座位
	 * @param mv
	 * @return
	 */
	public static SeatResult randomDZSeat(List<Map<String,Object>> productplays)
	{
		try{
			Integer pid = 0;
			String vid = "";  //TODO 因为大剧院选座接口场 次 id为字符串型vid = 0; 
			Double total = 0.0;
			Integer inventoryFlag = 0; //是否有库存 0有1没有
			List<SeatDetails> listMap = new ArrayList<SeatDetails>();
			String randomSeatURL=null;
			for (Map<String, Object> playMap : productplays) {
				if(Integer.parseInt(playMap.get("xztypeid").toString())==0){
					  randomSeatURL = StringUtil.replace(OnlineSeat.INIT(OnlineSeat.RANDOMSEATURL.KEY), playMap.get("xzpriceid")+","+playMap.get("num").toString()+","+playMap.get("xztypeid").toString(), playMap.get("xzscreeningsid"), getOauth());
					log.info("电子票特殊流程randomSeatURL 地址为 普通票:{}",randomSeatURL);
				}else{
					int aa = Integer.parseInt(playMap.get("XZNUM").toString());
					int bb = Integer.parseInt(playMap.get("num").toString());
					Integer num = aa*bb;
					  randomSeatURL = StringUtil.replace(OnlineSeat.INIT(OnlineSeat.RANDOMSEATURL.KEY), playMap.get("xztypeid")+","+num+","+playMap.get("xztypeid").toString(), playMap.get("xzscreeningsid"), getOauth());
					log.info("电子票特殊流程randomSeatURL 地址为 套票:{}",randomSeatURL);	
				}
			
				
				SeatResponse randomSeat = Constants.OnlineSeat.callServiceJsonToSeatResponse(randomSeatURL);
				log.info("电子票特殊流程返回的字符串为:{}",randomSeat.toString());
				
				SeatResult seatResult = randomSeat.getResult();
				if (!StringUtil.isEmpty(randomSeat.getError()) && randomSeat.getError().contains("座位已不足")) {
					inventoryFlag = 1 ;
					break;
				}
				pid = seatResult.getPid();
				vid = seatResult.getVid()+"";
				total += seatResult.getTotal();
				
				if(randomSeat.getCode().intValue() == 0){
					listMap.addAll(seatResult.getSeats());
				}
			}
			
			
			//只支持但场次多票价
//			{pid=1259, vid=6202, total=200, seats=[{pinfo=无座位, sid=5723, priceid=2, price=100, tptypeid=0, tpid=0}, {pinfo=无座位, sid=5724, priceid=2, price=100, tptypeid=0, tpid=0}]}
//			{pid=1259, vid=6202, total=400, seats=[{pinfo=无座位, sid=9771, priceid=3, price=200, tptypeid=0, tpid=0}, {pinfo=无座位, sid=9772, priceid=3, price=200, tptypeid=0, tpid=0}]}
			
			SeatResult seatResult = new SeatResult();
			seatResult.setPid(pid);
			seatResult.setVid(vid);
			seatResult.setTotal(total);
			seatResult.setSeats(listMap);
			if (inventoryFlag == 1) {
				seatResult.setData1("库存不足");
			}

			return seatResult;
			//特殊电子票流程
		}catch (Exception e) {
			log.error("异常信息", e);
		}
		return null;
	}
	/**
	 * @description 
	 * 功能描述: 获取当前时间验证的加密串
	 * @author 		  作         者: 张嘉杰
	 * @param	             参         数: 
	 * @return       返回类型: 
	 * @createdate   建立日期：Aug 23, 20136:29:10 PM
	 */
	public static String getOauth()
	{
		long day = 0;
		SimpleDateFormat data = new SimpleDateFormat("yyyy-MM-dd 00:00:00");
		try {
			day = new Date().getTime() - data.parse(data.format(new Date())).getTime();
		} catch (Exception e) {
			log.error("错误信息",e);
		}
		day = day / (1000 * 60);
		String oauth = 139 + "-" + day; //组合日期加密格式
		oauth = encrypt(oauth,Constants.BASE64_ONLINESEAT_ESDKEY); //EDS加密
		oauth = URLEncoder.encode(oauth); //URL转码 
		return oauth;
	}
	
	public static String getFullURL(HttpServletRequest request) {

		StringBuffer url = request.getRequestURL();
		if (request.getQueryString() != null) {
			url.append("?");
			url.append(request.getQueryString());
		}
		return url.toString();
	}
	/**
	 * 
	 * @description 
	 * 功能描述: 取网站前台-_-当前会话中的联盟id
	 * @author 		蔡晓青
	 * @param	          
	 * @return      
	 * @createdate  2013-8-29上午9:42:02
	 */
	public static String currentUnionId(HttpSession session){
		TunionBean unionInfo = (TunionBean) session.getAttribute("unionInfo");
		if(null != unionInfo){
			return (String) unionInfo.getUnionid();
		}
		return "0";
	}
}
